// Copyright Epic Games, Inc. All Rights Reserved.

#include "LyraHUD.h"

#include "AbilitySystemComponent.h"
#include "AbilitySystemGlobals.h"
#include "Async/TaskGraphInterfaces.h"
#include "Components/GameFrameworkComponentManager.h"
#include "UObject/UObjectIterator.h"

#include UE_INLINE_GENERATED_CPP_BY_NAME(LyraHUD)

class AActor;
class UWorld;

//////////////////////////////////////////////////////////////////////
// ALyraHUD

/**
 * 构造函数
 * @param ObjectInitializer 对象初始化器
 */
ALyraHUD::ALyraHUD(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer) // 调用父类构造函数
{
	PrimaryActorTick.bStartWithTickEnabled = false; // 设置开始时不允许Tick
}

/**
 * 预初始化组件
 * 将HUD添加到游戏框架组件接收器
 */
void ALyraHUD::PreInitializeComponents()
{
	Super::PreInitializeComponents(); // 调用父类方法

	UGameFrameworkComponentManager::AddGameFrameworkComponentReceiver(this); // 添加游戏框架组件接收器
}

/**
 * 开始播放
 * 发送游戏框架组件扩展事件
 */
void ALyraHUD::BeginPlay()
{
	UGameFrameworkComponentManager::SendGameFrameworkComponentExtensionEvent(this, UGameFrameworkComponentManager::NAME_GameActorReady); // 发送游戏角色就绪事件

	Super::BeginPlay(); // 调用父类方法
}

/**
 * 结束播放
 * 从游戏框架组件接收器中移除HUD
 * @param EndPlayReason 结束播放的原因
 */
void ALyraHUD::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
	UGameFrameworkComponentManager::RemoveGameFrameworkComponentReceiver(this); // 移除游戏框架组件接收器

	Super::EndPlay(EndPlayReason); // 调用父类方法
}

/**
 * 获取调试角色列表
 * 添加所有拥有能力系统组件的角色到调试列表
 * @param InOutList 输入输出列表
 */
void ALyraHUD::GetDebugActorList(TArray<AActor*>& InOutList)
{
	UWorld* World = GetWorld(); // 获取世界

	Super::GetDebugActorList(InOutList); // 调用父类方法

	// 添加所有拥有能力系统组件的角色
	for (TObjectIterator<UAbilitySystemComponent> It; It; ++It) // 遍历所有能力系统组件
	{
		if (UAbilitySystemComponent* ASC = *It) // 获取能力系统组件
		{
			if (!ASC->HasAnyFlags(RF_ClassDefaultObject | RF_ArchetypeObject)) // 检查不是类默认对象或原型对象
			{
				AActor* AvatarActor = ASC->GetAvatarActor(); // 获取化身角色
				AActor* OwnerActor = ASC->GetOwnerActor(); // 获取所有者角色

				if (AvatarActor && UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(AvatarActor)) // 如果化身角色存在且有有效的能力系统组件
				{
					AddActorToDebugList(AvatarActor, InOutList, World); // 添加化身角色到调试列表
				}
				else if (OwnerActor && UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(OwnerActor)) // 如果所有者角色存在且有有效的能力系统组件
				{
					AddActorToDebugList(OwnerActor, InOutList, World); // 添加所有者角色到调试列表
				}
			}
		}
	}
}